マルチVPCにおけるVPCエンドポイントの集約構成をTerraformで構築してみた
AWS事業本部のイシザワです。
今回はマルチVPC環境におけるVPCエンドポイントの集約構成をTerraformで構築してみます。
以下の記事の続き物です。この記事単体でも読めるようにしていますが、名前解決の集約は既に行っていることを前提とします。
構成要素
VPCエンドポイント
AWS SDKやAWS CLIを使ってAWSサービスの操作を行うにはAWSサービスエンドポイントにアクセスする必要があります。リージョナルサービスでは各リージョンにエンドポイントがあり、例えば東京リージョンのAWS Systems Managerであれば以下のURLがサービスエンドポイントとなります。
https://ssm.ap-northeast-1.amazonaws.com
このサービスエンドポイントはパブリックインターフェースなので、EC2からサービスエンドポイントにアクセスするためにはインターネットゲートウェイを経由する必要があります。
試しにEC2インスタンスからssm.ap-northeast-1.amazonaws.com
を名前解決するとパブリックIPが返ってくることが確認できます。
$ resolvectl query ssm.ap-northeast-1.amazonaws.com ssm.ap-northeast-1.amazonaws.com: 52.119.221.73 -- link: ens5 -- Information acquired via protocol DNS in 2.1ms. -- Data is authenticated: no; Data was acquired via local or encrypted transport: no -- Data from: network
VPCエンドポイントはAWSのサービスにプライベートにアクセスするための仕組みです。インターフェース型とゲートウェイ型のVPCエンドポイントがありますが、ゲートウェイ型だと他VPCから直接アクセスすることができないので集約構成においてはインターフェース型を使用します。
インターフェース型のエンドポイントでは、ネットワークインターフェースを作成するサブネットを指定します。このエンドポイントにはDNS名でアクセスします。
Route 53 Private Hosted Zone
Route 53 Private Hosted Zoneは関連付けたVPC内で利用できるDNSコンテンツサーバです。
AWS SDKやAWS CLIを使うとデフォルトではDNS名が[service_code].[region_code].amazonaws.com
で表されるAWSサービスエンドポイントにアクセスします。
Route 53 Private Hosted Zoneにエイリアスレコードを追加することで、このDNS名に対するアクセスをVPCエンドポイントに向かわせることができます。
Transit Gateway
名前解決の集約構成と同様に、VPCどうしを接続するために使用します。
VPC IPAM (IP Address Manager)
名前解決の集約構成と同様に、CIDRの重複を避けるために使用します。
全体構成
以下の構成によりVPCエンドポイントをVPCエンドポイント集約VPCに集約します。
- VPCエンドポイント集約VPCにVPCエンドポイントを作成する。
- AWSサービスエンドポイントへのアクセスを↑で作成したVPCエンドポイントに向かわせるためのRoute 53 Private Hosted Zoneを名前解決VPCに作成する。
全体の構成は以下の図の通りです。今回はSSMセッションマネージャーをインターネットゲートウェイの無いワークロードVPCから利用できるようにします。
Terraformコード
ソースコードはGitHubに載せています。いくつかピックアップして解説をしていきます。
VPCエンドポイント
VPCエンドポイントにアタッチするセキュリティグループを作成します。VPCエンドポイントにはHTTPSでアクセスするのでインバウンドルールで443/tcpを許可します。
resource "aws_security_group" "allow_https" { name = "allow_https" description = "Allow HTTPS inbound traffic" vpc_id = aws_vpc.main.id ingress { from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = [var.toplevel_pool_cidr] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "allow_https" } }
VPCエンドポイントのプライベートDNSは集約構成の場合は不要のため無効にしています。 これを有効にすると作成したVPCにAWS管理のPrivate Hosted Zoneが作成されて、デフォルトのサービスエンドポイントのDNS名とVPCエンドポイントのDNS名を関連付けるエイリアスレコードが作成されます。 集約構成で無い場合はRoute 53の設定が不要となるので設定することをお勧めします。
locals { service_name = "com.amazonaws.${var.region_name}.${var.service_code}" domain_name = "${var.service_code}.${var.region_name}.amazonaws.com" } resource "aws_vpc_endpoint" "main" { vpc_id = var.vpc_id subnet_ids = [var.subnet_id] vpc_endpoint_type = "Interface" service_name = local.service_name private_dns_enabled = false security_group_ids = [var.security_group_id] tags = { Name = "${var.system_id}-vpce-${var.service_code}" } }
Route 53 Private Hosted Zone
デフォルトのサービスエンドポイントのDNS名とVPCエンドポイントのDNS名を関連付けるエイリアスレコードをPrivate Hosted Zoneに登録します。
インターフェースのDNS名はdns_entry[0]["dns_name"]
で、DNS名が登録されているホストゾーンIDはdns_entry[0]["hosted_zone_id"]
で参照できます。
Private Hosted ZoneはVPCエンドポイントごとに作成します。
locals { service_name = "com.amazonaws.${var.region_name}.${var.service_code}" domain_name = "${var.service_code}.${var.region_name}.amazonaws.com" } resource "aws_vpc_endpoint" "main" { vpc_id = var.vpc_id subnet_ids = [var.subnet_id] vpc_endpoint_type = "Interface" service_name = local.service_name private_dns_enabled = false security_group_ids = [var.security_group_id] tags = { Name = "${var.system_id}-vpce-${var.service_code}" } } resource "aws_route53_zone" "main" { name = local.domain_name vpc { vpc_id = var.dns_vpc_id } } resource "aws_route53_record" "main" { zone_id = aws_route53_zone.main.id name = local.domain_name type = "A" alias { name = aws_vpc_endpoint.main.dns_entry[0]["dns_name"] zone_id = aws_vpc_endpoint.main.dns_entry[0]["hosted_zone_id"] evaluate_target_health = false } }
動作確認
作成したsample-workload0-test-instance
にSSMセッションマネージャーでログインできることを確認します。
念のためログイン後にssm.ap-northeast-1.amazonaws.com
を名前解決して、プライベートIPが返ってくることを確認します。
$ resolvectl query ssm.ap-northeast-1.amazonaws.com ssm.ap-northeast-1.amazonaws.com: 10.0.0.154 -- link: ens5 -- Information acquired via protocol DNS in 13.6ms. -- Data is authenticated: no; Data was acquired via local or encrypted transport: no -- Data from: network
まとめ
VPCエンドポイントの集約構成をTerraformで作成してみました。名前解決の集約構成と合わせることで、VPCエンドポイント用のPrivate Hosted Zoneの設定を1箇所で済ませることができます。 VPCエンドポイントの集約を行う際は名前解決の集約もぜひ検討してみてください。
次回はインターネットへの通信の集約をしてみようと思います。